<?php

/*------------------------------------------------
*
*   Explay Engine Content Management System.
*   Copyright © 2008 Golovdinov Alexander.
*
*-------------------------------------------------
*
*   Official site: wwww.alex-home.spb.ru/explay.html
*   Contact e-mail: golovdinov@gmail.com
*
*   GNU General Public License original source:
*   http://www.gnu.org/licenses/gpl-3.0.html
*
------------------------------------------------*/

if (!defined ('EXPLAY')) exit;

/**
 * СORE
 *
 * Контроль модулей, обработка и вывод страницы.
 */

class CORE {
	
	protected $db;
	public $module_name = 'start_page';
	public static $module_header = '';
	public $theme;
	public $global_template_href;
	public static $global_template_html;
	
	public static $body;
	public static $title;
	
	public static $SITE = array ();
	
	public $second_navigation;
	private static $panels_top;
	private static $panels_bottom;
	private static $blocks_left;
	private static $blocks_right;
	
	public $module_href = false;
	public $module_plugin_href = false;
	public $break_page_generation = false; // при установке в true запрещается парсин шаблона страницы и выводится только контент
	
	private static $instance = false;
	public static function getInstance () {
		if (self::$instance === false) self::$instance = new CORE;
			
		return self::$instance;
	}
	
	/**
	 * Конструктор
	 */
	private function __construct () {
		$this->db = MySQL::getInstance();
	}
	
	/**
	 * Устанавливает заголовок
	 *
	 * @param string $string текст заголовка
	 */
	public static function set_page_title ($string) {
		$string = str_replace ('{module_header}', self::$module_header, $string);
		
		self::$title = $string;
	}
	
	/**
	 * Устанавливает ключевые слова
	 *
	 * @param string $string ключевые слова
	 */
	public static function set_keywords ($string) {
		self::$SITE['site_keywords'] = $string;
	}
	
	/**
	 * Даваляет контент блока к переменным $left_blocks или $right_blocks
	 *
	 * @param string $content контент блока
	 * @param string $align позиция, left или right
	 */
	public static function add_block ($content, $align) {
		($align == 'left')
			? self::$blocks_left .= $content
			: self::$blocks_right .= $content;
	}
	
	/**
	 * Даваляет контент панели к переменным $panels_top или $panels_bottom
	 *
	 * @param string $content контент панели
	 * @param string $align позиция, top или bottom
	 */
	public static function add_panel ($content, $align) {
		($align == 'top')
			? self::$panels_top .= $content
			: self::$panels_bottom .= $content;
	}
	
	/**
	 * Заменяет участок HTML-кода на странице
	 *
	 * @param string $param заменяемый участок
	 * @param string $contetn контент
	 */
	 public static function body_replace ($param, $content) {
	 	self::$global_template_html = str_replace ($param, $content, self::$global_template_html);
	 }
	 
	
	/**
	 * Контроль сессии пользователя
	 *
	 * @param integer $uid id пользователя
	 * @param string $ugroup группа пользователя
	 */
	public function session ($uid, $ugroup) {
		
		//$page_name = $this->title;
		$ip = $_SERVER['REMOTE_ADDR'];
		$sessid = $_SESSION['unical_sesid'];
		
		$get_usr = $this->db->query ("SELECT * FROM ".DB_PEREFIX."_sessions WHERE sesid = '$sessid'");
		
		if ($this->db->num_rows($get_usr) == 0)
			$this->db->query ("INSERT INTO ".DB_PEREFIX."_sessions VALUES ('$ugroup', '".time()."', '$uid', '$ip', '".self::$module_header."', '$sessid')");
		else
			$this->db->query ("UPDATE ".DB_PEREFIX."_sessions SET utime = '".time()."', uid = '$uid', ugroup = '$ugroup', page = '".self::$module_header."' WHERE sesid = '$sessid'");
		
		$this->db->query ("DELETE FROM ".DB_PEREFIX."_sessions WHERE utime <".(time()-300));
		
		
		// Обновление последнего визита пользователя.
		$this->db->query ("UPDATE ".DB_PEREFIX."_users SET lastvisit = ".time()." WHERE user_id = $uid");
	}
	
	/**
	 * Инициализация страниицы
	 */
	public function make_page () {
		
		
		// Если запрещен парсинг шаблона страницы выводим только контен
		if ($this->break_page_generation) {
			print self::$body;
			return true;	
		}
		
		Templater::set_var ('SITE', self::$SITE);
		Templater::set_var ('title', self::$title);
		self::$global_template_html = Templater::display ($this->global_template_href);
		
		preg_match_all ("#<include_php=(.+?)>#is", self::$global_template_html, $include_php);
		
		for ($i=0; $i<count($include_php[0]); $i++) {
			$this->include_php ("<include_php={$include_php[1][$i]}>");
		}
		
		if (preg_match("#{left_blocks}#is", self::$global_template_html) || preg_match("#{right_blocks}#is", self::$global_template_html)) $this->make_blocks ();
		if (preg_match("#{top_panels}#is", self::$global_template_html) || preg_match("#{bottom_panels}#is", self::$global_template_html)) $this->make_panels ();
		
		$this->prepare_template ();
		
		print self::$global_template_html;
	}
	
	/**
	 * Замена основных переменных в шаблоне страницы
	 */
	private function prepare_template () {
		self::$global_template_html = str_replace ('{LEFT_BLOCKS}', self::$blocks_left, self::$global_template_html);
		self::$global_template_html = str_replace ('{RIGHT_BLOCKS}', self::$blocks_right, self::$global_template_html);
		self::$global_template_html = str_replace ('{TOP_PANELS}', self::$panels_top, self::$global_template_html);
		self::$global_template_html = str_replace ('{BOTTOM_PANELS}', self::$panels_bottom, self::$global_template_html);
		self::$global_template_html = str_replace ('{SECOND_NAVIGATION}', $this->second_navigation, self::$global_template_html);
		self::$global_template_html = str_replace ('{BODY}', self::$body, self::$global_template_html);
	}
	
	/**
	 * Выборка блоков из БД
	 */
	protected function make_blocks () {
		($this->module_name == '') ? $page = 'start_page' : $page = $this->module_name;
		
		$get_blocks = $this->db->query ("SELECT block_header, block_name, block_body, block_file, block_group, block_align, block_pages FROM ".DB_PEREFIX."_blocks WHERE block_visible = 'visible' ORDER BY block_pos");
		
		while (list($header, $name, $body, $file, $group, $align, $pages) = $this->db->fetch_row ($get_blocks)) {
			$module_allowed = false;
			$group_allowed = false;
			
			if ($pages != 'all') {
				$pages = explode (',', $pages);
				foreach ($pages as $p) if ($p == $page) $module_allowed = true;
			}
			else $module_allowed = true;
			
			if ($group == 'all' || is_registered()) $group_allowed = true;
			
			// input block
			
			if ($module_allowed && $group_allowed)
				($file != '' && $body == '')
					? block ($header, $name, $file, 'f', $align)
					: block ($header, $name, $body, 't', $align);
		}
	}
	
	
	/**
	 * Выборка панелей из БД
	 */
	protected function make_panels () {
		
		($this->module_name == '' || $this->module_name == 'start_page') ? $module_name = 'start' : $module_name = $this->module_name;
		
		$get_panels = $this->db->query ("SELECT * FROM ".DB_PEREFIX."_panels WHERE panel_status = 'on' AND (panel_pages = 'all' OR panel_pages = '$module_name')");

		while ($panel = $this->db->fetch_array ($get_panels)) {
			if ($panel['panel_day'] != 0 && $panel['panel_day'] != '') {
				$day = $panel['panel_day'] * 86400;
				$ost = ($panel['panel_date'] + $day) - time();
				if ($ost < 0) $db->query ("UPDATE ".DB_PEREFIX."_panels SET panel_status = 'off' WHERE panel_id = '".$panel['panel_id']."'");
			}
			if ($panel['panel_group'] == 'all' || is_registered()) {
				if ($panel['panel_align'] == 'top') {
				
					if ($panel['panel_file'] != '')
						CORE_include_panel ($panel['panel_file'], $panel['panel_align']);
					elseif ($panel['panel_file'] == "" && $panel['panel_table'] == 'use')
						self::$panels_top .= past_table ($panel['panel_header'], $panel['panel_body'], true);
					else
						self::$panels_top .= $panel['panel_body'];
						
				} else {
					
					if ($panel['panel_file'] != '')
						CORE_include_panel ($panel['panel_file'], $panel['panel_align']);
					elseif ($panel['panel_file'] == '' && $panel['panel_table'] == 'use')
						self::$panels_bottom .= past_table ($panel['panel_header'], $panel['panel_body'], true);
					else
						self::$panels_bottom .= $panel['panel_body'];
						
				}
			}
		}
	}
	
	
	
	/**
	 * Подключение в шаблон PHP-файла
	 *
	 * Создается переменная $replace_var, котрая должна быть заменена блоком в шаблоне страницы
	 *
	 * @param string $var переменная в шаблоне вида <include_php=file.php>
	 */
	protected function include_php ($var) {
		$replace_var = $var;
		$var = str_replace ('<include_php=', '', $var);
		$var = str_replace ('>', '', $var);
		$var = str_replace ('"', '', $var);
		$var = str_replace ("'", '', $var);
		
		if (file_exists ($_SERVER['DOCUMENT_ROOT'].'/'.$var))
			CORE_include_php ($var, $replace_var );
		else
			self::$global_template_html = str_replace ($replace_var, 'None request file!', self::$global_template_html);
	}
	
	
	/**
	 * Инициализация подключаемого модуля (файла)
	 */
	public function controller () {
		
		if (!empty($_GET['name'])) {
			
			$break = false;
			
			//
			// Проверяем $_GET['name'] на названия зарегистрированных модулей
			//
			switch ($_GET['name']) {
				case 'ajax' : {
					$this->module_href = $_SERVER['DOCUMENT_ROOT'].'/modules/ajax/index.php';
					$this->break_page_generation = true;
					$break = true;
					break;
				}
				case 'api' : {
					$this->module_href = $_SERVER['DOCUMENT_ROOT'].'/modules/api/index.php';
					$this->break_page_generation = true;
					$break = true;
					break;
				}
			}
			
			if ($break) return;
			
			$this->module_name = addslashes(trim($_GET['name']));
			
			// Ищем модуль в базе
			$get_module = $this->db->query ("SELECT * FROM ".DB_PEREFIX."_modules WHERE module_name = '".$this->module_name."'");
			
			if ($this->db->num_rows ($get_module) == 1) {
				
				$MODULE = $this->db->fetch_array ($get_module);
				$include_module_file = $_SERVER['DOCUMENT_ROOT'].'/'.$MODULE['module_file'];
				
				// Устанавливаем заголовок
				self::$module_header = $MODULE['module_header'];
				self::set_page_title ($MODULE['module_header'].' &mdash; '.self::$SITE['site_name']);
				
				// поключаем плагин к модулю
				if ($MODULE['module_plugin'] != '') {
					if (file_exists($MODULE['module_plugin']))
						$this->module_plugin_href = $_SERVER['DOCUMENT_ROOT'].'/'.$MODULE['module_plugin'];
				}
				
				
				// выбираем шаблон
				if (file_exists($_SERVER['DOCUMENT_ROOT'].'/themes/'.$this->theme.'/module_'.$this->module_name.'.tpl'))
					$this->global_template_href = 'module_'.$this->module_name.'.tpl';
				
				elseif (file_exists($_SERVER['DOCUMENT_ROOT'].'/themes/'.$this->theme.'/modules_template.tpl'))
					$this->global_template_href = 'modules_template.tpl';
				
			
					
				
				// подключаем файл
				if ($MODULE['module_status'] == 'on' && file_exists($include_module_file)) {
					
					if ($MODULE['module_group'] == 'all')
						$this->module_href = $include_module_file;
					
					elseif ($MODULE['module_group'] == 'register') {
						if (is_registered()) 
							$this->module_href = $include_module_file;
						else
							error_403 ();
					
					} else {
					
						if (is_moderator() || is_admin())
							$this->module_href = $include_module_file;
						else
							error_403 ();
					}
				}
				elseif ($MODULE['module_status'] == 'off') site_error ('В данный момент модуль неактивен или нет файла!');
				
				
			}
			else error_404 ();
		
		// Если модуль не указан, то выводим главную
		} else {
			if (   file_exists($_SERVER['DOCUMENT_ROOT'].'/'.self::$SITE['site_main'])
				&& preg_match("#{body}#is", file_get_contents ( $_SERVER['DOCUMENT_ROOT'].'/themes/'.$this->theme.'/'.$this->global_template_href)))
					$this->module_href = $_SERVER['DOCUMENT_ROOT'].'/'.self::$SITE['site_main'];
		}
		
	}
	
	
}


// Функция для подключения php-файлов в шаблон ядра

function CORE_include_php ($file, $replace) {
	global $db, $GLOBAL_USER, $SITE, $CORE;
	include $_SERVER['DOCUMENT_ROOT'].'/'.$file;
}

function CORE_include_panel ($file, $align) {
	global $db, $GLOBAL_USER, $SITE, $CORE;
	include $_SERVER['DOCUMENT_ROOT'].'/'.$file;
}	
